package com.zhr.tools.code3;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.zhr.tools.FileUtil;
import com.zhr.tools.StringUtils;
import com.zhr.tools.code3.entity.ClassFieldInfo;
import com.zhr.tools.code3.entity.ClassInfo;
import com.zhr.tools.code3.scanner.ClassFieldInfoScanner;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * @author a
 */
public class CreateClassCode {

    /**
     * 生成实体类
     *
     * @param classInfo 类信息
     */
    private static String getClassCode(ClassInfo classInfo) {
        if (classInfo.getFields().size() <= 0) {
            System.err.println("没有实体类信息 生成实体类");
            return "";
        }
        StringBuilder sb = new StringBuilder();
        //package
        if (StrUtil.isNotEmpty(classInfo.getPackagePath())) {
            sb.append(classInfo.getPackagePath()).append("\n");
        }
        // 类的引用
        if (classInfo.isUseLombok()) {
            sb.append("import lombok.Data;\n");
            if (classInfo.isUseChain()) {
                sb.append("import lombok.experimental.Accessors;\n");
            }
        }
        classInfo.getImports().forEach(sb::append);
        // 类的注释
        sb.append("/**\n")
                .append("* ").append(classInfo.getMemo()).append("\n")
                .append("* @author ").append(classInfo.getAuthor()).append("\n")
                .append("* @date ").append(DateUtil.format(classInfo.getCreateDate(), "yyyy-MM-dd")).append("\n")
                .append("*/\n");
        //类的注解
        if (classInfo.isUseLombok()) {
            sb.append("@Data\n");
            if (classInfo.isUseChain()) {
                sb.append("@Accessors(chain = true)\n");
            }
        }
        // 类的标题
        sb.append("public class ").append(classInfo.getName()).append(" {\n");
        // 类的变量
        for (ClassFieldInfo classFieldInfo : classInfo.getFields()) {
            sb.append("\n\t/**\n\t * ").append(classFieldInfo.getMemo()).append("\n\t */");
            sb.append("\n\tprivate ").append(classFieldInfo.getType()).append(" ").append(classFieldInfo.getVariableName()).append(";");
        }
        sb.append("\n");

        if (!classInfo.isUseLombok()) {
            // set get方法
            for (ClassFieldInfo classFieldInfo : classInfo.getFields()) {
                if (classInfo.isUseChain()) {
                    sb.append("\r\n\tpublic void set").append(classFieldInfo.getVariableNameUpperFirst()).append("(").append(classFieldInfo.getType()).append(classFieldInfo.getVariableName()).append(") {")
                            .append("\r\n\t\tthis.").append(classFieldInfo.getVariableName()).append(" = ").append(classFieldInfo.getVariableName()).append(";")
                            .append("\n}\r\n")
                            .append("\n\tpublic ").append(classFieldInfo.getType()).append(" get").append(classFieldInfo.getVariableNameUpperFirst()).append("() {")
                            .append("\n\t\treturn ").append(classFieldInfo.getVariableName()).append(";")
                            .append("\n}\r\n");
                } else {
                    sb.append("\r\n\tpublic ").append(classInfo.getName()).append(" set").append(classFieldInfo.getVariableNameUpperFirst()).append("(").append(classFieldInfo.getType()).append(classFieldInfo.getVariableName()).append(") {")
                            .append("\r\n\t\tthis.").append(classFieldInfo.getVariableName()).append(" = ").append(classFieldInfo.getVariableName()).append(";")
                            .append("\n\treturn this;")
                            .append("\n}\r\n")
                            .append("\n\tpublic ").append(classFieldInfo.getType()).append(" get").append(classFieldInfo.getVariableNameUpperFirst()).append("() {")
                            .append("\n\t\treturn ").append(classFieldInfo.getVariableName()).append(";")
                            .append("\n}\r\n");
                }

            }
        }
        sb.append("\n}");
        return sb.toString();
    }

    public static void createClass(String className, String classMemo, String classAuthor, String filePath, String targetClassPath, String packagePath) throws IOException {
        if (StrUtil.isEmpty(className)) {
            throw new RuntimeException("生成的类名不能为空");
        } else {
            className = StringUtils.upperFirstLatter(className);
        }
        String codeHome = System.getProperty("user.dir") + File.separatorChar
                + "src" + File.separatorChar + "main" + File.separatorChar + "java" + File.separatorChar;
        String defaultScanPath = codeHome + "excel6.txt";
        String defaultTargetClassPath = codeHome + "com" + File.separatorChar + "zhr" + File.separatorChar + "code3" + File.separatorChar + "temp" + File.separatorChar + className + ".java";
        if (StrUtil.isEmpty(filePath)) {
            filePath = defaultScanPath;
        }
        if (StrUtil.isEmpty(targetClassPath)) {
            targetClassPath = defaultTargetClassPath;
        } else {
            targetClassPath = targetClassPath + File.separatorChar + className + ".java";
        }
        List<ClassFieldInfo> classFieldInfos = ClassFieldInfoScanner.scanClassFieldInfo(filePath);
        ClassInfo classInfo = new ClassInfo();
        classInfo.setName(className);
        classInfo.setFields(classFieldInfos);
        classInfo.setMemo(classMemo);
        classInfo.setAuthor(classAuthor);
        classInfo.setCreateDate(new Date());
        classInfo.setPackagePath(packagePath);
        String classCode = getClassCode(classInfo);
        FileUtil.saveFileString(classCode, new File(targetClassPath));
    }

    /**
     * 生成类的文本
     *
     * @param className   类名
     * @param classMemo   类注释
     * @param classAuthor 作者
     * @param data        Excel复制过来的字段
     * @param packagePath 包路径
     * @return 生成类的文本
     */
    public static String createClassStr(String className, String classMemo, String classAuthor,
                                        String data, String packagePath, Boolean useLombok) {
        if (StrUtil.isEmpty(className)) {
            throw new RuntimeException("生成的类名不能为空");
        } else {
            className = StringUtils.upperFirstLatter(className);
        }
        List<ClassFieldInfo> classFieldInfos = ClassFieldInfoScanner.scanClassFieldInfoFromString(data);
        ClassInfo classInfo = new ClassInfo();
        classInfo.setName(className);
        classInfo.setFields(classFieldInfos);
        classInfo.setMemo(classMemo);
        classInfo.setAuthor(classAuthor);
        classInfo.setCreateDate(new Date());
        classInfo.setPackagePath(packagePath);
        classInfo.setUseLombok(useLombok);
        return getClassCode(classInfo);
    }
}
